/*
 * Copyright (c) 2023 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef APPFRAMEWORK_UTILS_CONST_EXPR_UTIL_H_
#define APPFRAMEWORK_UTILS_CONST_EXPR_UTIL_H_

#include <array>

namespace keels {
namespace utils {

template<typename T, typename... Args>
constexpr auto make_constexpr_array(Args&&... args) -> std::array<T, sizeof...(Args)>
{
    return { std::forward<Args>(args)... };
}

template<typename T>
constexpr void constexpr_swap(T& a, T& b)
{
    T tmp = a;
    a = b;
    b = tmp;
}

template<typename T, std::size_t N>
constexpr std::array<T, N> const_bubble_sort(std::array<T, N> arr)
{
    for (std::size_t i = 0; i < N; ++i) {
        for (std::size_t j = 0; j < N - 1; ++j) {
            if (arr[j + 1] < arr[j]) {
                constexpr_swap(arr[j], arr[j + 1]);
            }
        }
    }
    return arr;
}

template<typename T, typename... Args>
constexpr auto make_constexpr_sorted_array(Args&&... args) -> std::array<T, sizeof...(Args)>
{
    std::array<T, sizeof...(Args)> item = { std::forward<Args>(args)... };
    return const_bubble_sort(item);
}

constexpr bool constexpr_str_less(const char* a, const char* b)
{
    if (a == nullptr && b != nullptr)
        return true;
    if (a != nullptr && b == nullptr)
        return false;
    while (*a != '\0' && *a == *b) {
        a++;
        b++;
    }
    return *a < *b;
}

} // namespace utils
} // namespace keels

#endif